package com.hdax.search.thread;

import java.util.concurrent.*;

public class XianChengChi {

    /**
     * 线程池
     */

    /**
     * 区别
     *
     *  1、不能得到返回值，
     *  可以得到返回值
     *  都不能控制资源
     *  可以控制资源，性能稳定
     */


    /**
     * 1、创建线程
     */
    public static ExecutorService service = Executors.newFixedThreadPool(10);

    /**
     * 七大线程
     * 2、创建线程
     *      1、corePoolSize核心线程数[一直存在]:线程池，创建好之后就准备就绪的线程数量
     *      2、maximumPoolSize:【200】最大线程数量，控制资源并发
     *      3、keepAliveTime:存活时间，如果当前正在运行的线程数量大于核心数量。
     *          释放空闲的线程，只要线程空闲大于，指定的存活时间
     *      4、TimeUnit:时间单位
     *      5、BlockingQueue<Runnable>:阻塞队列，如果任务有很多，将目前多的任务放在队列里面
     *              只要有空闲的线程就会从队列里面,取出新的任务继续执行
     *      6、ThreadFactory：线程的创建工厂
     *      7、RejectedExecutionHandler:如果队列满了，按照我们指定的拒绝策略，拒绝执行任务，
     *
     *  工作顺序
     *      1、线程池创建，准备好core数量的核心线程，准备接受任务
     *      2、新的线程进来，用core准备的空闲线程执行
     *          1、core核心线程数满了，就将进来的任务放入阻塞对列中，空闲的core就会自己去阻塞队列中获取任务执行
     *          2、阻塞满了，就直接开启新的线程执行，最大只能开到max指定的数量
     *          3、如果线程数开到了max的数量，还有新任务进来，就会使用reject，指定的拒绝策略进行执行
     *          4、max最大线程都执行完了，有很多空闲，再指定的时间，keepAliveTime存活时间，释放max-core这些线程
     *
     *
     *   new LinkedBlockingDeque<>(),//默认是Integer最大值
     *
     *
     *
     * 一个线程池 core7个，max20个，queue：50，100个并发进来怎么分配、
     * 7个立即执行，50个会进入队列，再开13个进行执行，剩下的30个使用就使用拒绝策略来执行
     *
     *
     * 优点：1、降低资源的消耗
     *      通过重复利用已经创建好的线程 降低创建线程和销毁线程带带来的损耗
     *     2、提高响应速度
     *
     */

    public static ThreadPoolExecutor executor=new ThreadPoolExecutor(5,
            4,
            200,
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(10000),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());
    public static void main(String[] args) {

        executor.execute(new ThreadTest.Thread01());

        Executors.newCachedThreadPool(); //core是0，所有都可回收
        Executors.newCachedThreadPool(); //固定大小，core=max都不可回收
        Executors.newSingleThreadExecutor();//单线程的线程池
//        Executors.newScheduledThreadPool();//定时任务的线程池
        //把线程丢进线程池
        service.execute(new RunnableTest.Runnable01());
    }
}
